/**
 * Created by tianling on 2016/12/25.
 */

module.exports = class {
    constructor() {
        this.key = "iframe:dict";
    }

    static init() {
        return new this();
    }

    /**
     * 获取系统模块列表
     */
    async getDictItemsByDB() {
        return await global.DataBase.iframe_dict.Access.findAll({
            where: {
                zd_IsShow: 1
            },
            order: ['zd_sort'],
            raw: true
        });
    };

    async Sync() {

        let ret = {};
        let iframe_dict = await this.getDictItemsByDB();
        let labels = await global.DataBase.base.query("select distinct zd_label from iframe_dict ");
        for (let label of labels) {
            if (label.zd_label.length > 0) {
                ret[label.zd_label] = await global.DataBase.iframe_dict.Access.findAll({
                    where: {
                        zd_label: label.zd_label
                    },
                    raw: true
                })
            }
        }
        ret['all'] = iframe_dict;
        if (!global.Config.isShareMemory) {
            global.iframe_dict = ret;
        } else {
            let redisClient = global.Redis.getClient();
            let pipeline = redisClient.pipeline();
            for (let key in ret) {
                if (key) {
                    pipeline.set(this.key + ":" + key, JSON.stringify(ret[key]));
                }
            }
            await pipeline.exec();


        }
        log.info("加载字典表成功");
        return true;
    };


    /**
     * 获取指定Label的字典表
     * @param Label
     * @constructor
     */
    async GetDictItems(Label) {
        let DictItems = global.iframe_dict;
        if (Label) {
            if (!global.Config.isShareMemory) {
                return DictItems[Label];
            } else {
                let redisClient = global.Redis.getClient();
                let ret = await redisClient.get(this.key + ":" + Label);
                return JSON.parse(ret);
            }
        } else {
            if (!global.Config.isShareMemory) {
                DictItems = JSON.parse(JSON.stringify(DictItems['all']));
            } else {
                let redisClient = global.Redis.getClient();
                let ret = await redisClient.get(this.key + ":all");
                DictItems = JSON.parse(ret);
            }

            let labels = new Set();
            for (let i in DictItems) {
                labels.add(DictItems[i].zd_label);
            }

            let labelModels = [],
                index = 0;
            for (let it of labels.values()) {
                if (it && it !== '') {
                    labelModels.push({
                        key: Number('-' + (Number(index) + 1)),
                        value: it
                    });

                    DictItems.push({
                        zd_ID: Number('-' + (Number(index) + 1)),
                        zd_label: 'dictLabel',
                        zd_Name: it,
                        zd_value: it,
                        zd_ParentID: 0
                    });
                    index++;
                }

            }

            for (let a = 0; a < DictItems.length; a++) {
                let item = DictItems[a];
                if (item.zd_ParentID === 0 && item.zd_ID > 0) {
                    for (let i = 0; i < labelModels.length; i++) {
                        if (item.zd_label === labelModels[i].value) {
                            item.zd_ParentID = labelModels[i].key;
                            break;
                        }
                    }
                }
            }


        }
        return DictItems;
    };

    /**
     * 获取某个键值对
     * @param Label String
     * @param Name String
     * @returns {*}
     * @constructor
     */
    async GetDictItem(Label, value) {
        let DictItems = await this.GetDictItems(Label);
        let _items = DictItems.filter(function (item) {
            if (item.zd_label === Label && item.zd_value === value) {
                return true;
            }
        });
        if (_items.length > 0) {
            return _items[0];
        }
        return null;
    };


    async GetDictItemByID(ID) {
        let DictItems = await this.GetDictItems();
        let _items = DictItems.filter(function (item) {
            if (item.zd_ID === Number(ID)) {
                return true;
            }
        });
        if (_items.length > 0) {
            return _items[0];
        }
        return null;
    };

    /**
     * 获取相同分类下的一组值的名称
     * @param {String} Label  字典表分类
     * @param {Array} Values 值数组
     */
    async GetDictNames(Label, Values) {
        let Names = [];
        Values.map(async (item) => {
            if (item && item !== "") {
                let dict = await this.GetDictItem(Label, item);
                if (dict) {
                    Names.push(dict.zd_Name);
                }
            }
        });
        return Names;
    };

    async getChildrenValues(Label, value) {
        let cur = await this.GetDictItem(Label, value);
        let Items = await this.GetDictItems(Label);
        let Childrens = [];
        for (let i = 0; i < Items.length; i++) {
            let item = Items[i];
            if (item.zd_ParentID === cur.zd_ID) {
                Childrens.push("" + item.zd_value + "");
                if (item.zd_IsParent === 1) {
                    Childrens = Childrens.concat(await this.getChildrenValues(Label, item.zd_value));
                }
            }
        }
        return Childrens;
    };

    async getChildrensModel(Label, value) {
        let cur = await this.GetDictItem(Label, value);
        let Items = await this.GetDictItems(Label);
        let Childrens = [];
        for (let i = 0; i < Items.length; i++) {
            let item = Items[i];
            if (item.zd_ParentID == cur.zd_ID) {
                Childrens.push(item);
                if (item.zd_IsParent == 1) {
                    Childrens = Childrens.concat(await this.getChildrensModel(Label, item.zd_value));
                }
            }
        }
        return Childrens;
    };

    /**
     * 获取所有父级的值数组
     * @param {*} Label
     * @param {*} value
     */
    async GetParentsValue(Label, value) {
        let ParentsModels = await this.GetParentsModel(Label, value);
        let Values = [];
        for (let i = ParentsModels.length - 1; i > -1; i--) {
            Values.push(ParentsModels[i].zd_value);
        }
        return Values;
    };

    /**
     * 获取所有父级的名称数组
     * @param {*} Label
     * @param {*} value
     */
    async GetParentsName(Label, value) {
        let ParentsModels = await this.GetParentsModel(Label, value);
        let Names = [];
        for (let i = ParentsModels.length - 1; i > -1; i--) {
            Names.push(ParentsModels[i].zd_Name);
        }
        return Names;
    };

    /**获取所有的父级模型**/
    async GetParentsModel(Label, value) {
        let item = await GetDictItem(Label, value);
        if (item) {
            return await this.GetParentsModelByID(item.zd_ID);
        }
        return [];
    };

    async GetParentsModelByID(ChildrenID) {
        let Parents = [];
        let item = await this.GetDictItemByID(ChildrenID);
        if (item) {
            Parents.push(item);
            Parents = Parents.concat(await this.GetParentsModelByID(item.zd_ParentID));
        }
        return Parents;
    };

    async GetParentsValueByID(ChildrenID) {
        let Parents = [];
        let item = await this.GetDictItemByID(ChildrenID);
        if (item) {
            Parents.push(item.zd_value);
            Parents = Parents.concat(await this.GetParentsValueByID(item.zd_ParentID));
        }
        return Parents;
    };

    async GetTreeData(Label, ParentID, _Items) {
        let Items = [];
        if (_Items) {
            Items = _Items;
        } else {
            Items = await this.GetDictItems(Label);
        }

        //console.log('items:',Items);
        let data = [];
        let getChildrens = function (parentObj) {
            let cdata = [];

            let parentIds = parentObj.parentIds.split(',');
            parentIds.push(parentObj.key);
            //清洗parentIds
            for (let i = parentIds.length - 1; i >= 0; i--) {
                if (parentIds[i] < 0) parentIds.splice(i, 1);
            }
            for (let i = 0; i < Items.length; i++) {
                let item = Items[i];
                if (item.zd_ParentID == parentObj.key) {
                    let data_item = {
                        title: item.zd_Name,
                        value: Label ? item.zd_value : item.zd_label + '-' + item.zd_value,
                        key: item.zd_ID,
                        type: item.zd_label,
                        parentIds: parentIds.join(','),
                        checked: false
                    };
                    data_item.children = getChildrens(data_item);
                    if (data_item.children.length === 0) delete data_item.children;
                    cdata.push(data_item);
                }
            }
            return cdata;
        };
        if (ParentID > 0) {
            let curP = await this.GetDictItemByID(ParentID);
            let parentsModels = await this.GetParentsModel(curP.zd_label, curP.zd_value);
            let pids = [];
            parentsModels.map(function (item) {
                pids.push(item.zd_ID);
            });
            curP.parentIds = pids.join(',');
            data = getChildrens({
                key: curP.zd_ID,
                parentIds: curP.parentIds
            });
        } else {
            data = getChildrens({
                key: 0,
                parentIds: ''
            });
        }
        return data;

    };


    GetTreeData2(Label, ParentID, _Items) {
        let Items = [];
        if (_Items) {
            Items = _Items;
        } else {
            Items = this.GetDictItems(Label);
        }

        //console.log('items:',Items);
        let data = [];
        let getChildrens = function (pid) {
            let cdata = [];
            for (let i = 0; i < Items.length; i++) {
                let item = Items[i];
                if (item.zd_ParentID == pid) {
                    let data_item = {
                        title: item.zd_Name,
                        value: Label ? item.zd_value : item.zd_label + '-' + item.zd_value,
                        key: item.zd_ID,
                        type: item.zd_label,
                        children: getChildrens(item.zd_ID),

                        checked: false
                    };
                    if (data_item.children.length === 0) delete data_item.children;
                    cdata.push(data_item);
                }
            }
            return cdata;
        };
        if (ParentID > 0) {
            let curP = this.GetDictItemByID(ParentID);
            data.push({
                label: curP.zd_Name,
                value: label ? curP.zd_value : curP.zd_label + '-' + curP.zd_value,
                key: curP.zd_ID,
                type: curP.zd_label,
                children: getChildrens(curP.zd_ID),
                checked: false
            });
        } else {
            data = getChildrens(0);
        }
        return data;

    };
};